using System;
using System.Collections.Generic;
using System.Linq;
using Pay.DTO;
using Pay.IService;
using Pay.Data;
using Pay.Service.Cache;
using Pay.Core;
using Pay.TO;
using System.Data.Entity;
using System.Text;
using System.Threading.Tasks;
using Pay.DTO.hniao;
using Newtonsoft.Json.Linq;

namespace Pay.Service {
    public class ProductService : ServiceBase, IProductService, IDisposable {
        private IUnitOfWork _iUnitOfWork;
        private IMerchantService _iMerchantService;
        private ISettingService _iSettingService;
        private IShopInfoService _iShopInfoService;
        private IProductActivityService _iProductActivityService;
        public ProductService(IUnitOfWork iUnitOfWork, IMerchantService iMerchantService, ISettingService iSettingService, IShopInfoService iShopInfoService, IProductActivityService iProductActivityService) :
            base(iUnitOfWork) {
            _iUnitOfWork = iUnitOfWork;
            _iMerchantService = iMerchantService;
            _iSettingService = iSettingService;
            _iShopInfoService = iShopInfoService;
            _iProductActivityService = iProductActivityService;
        }
        /// <summary>
        /// 查询商品列表，不包含促销活动处
        /// </summary>
        /// <param name="goodsQuery"></param>
        /// <returns></returns>
        public PagedResult<product_dto> Get(GoodsQuery goodsQuery) {
            var filter = PredicateBuilder.True<Product>();
            if (goodsQuery.IsTokenMall) {//拓垦商城展示分销价格大于0的商品
                filter = filter.And(c => c.DistributionPrice != null && c.DistributionPrice > 0);
            }

            if (goodsQuery.Ids != null && goodsQuery.Ids.Length > 0) {
                filter = filter.And(c => !goodsQuery.Ids.Contains(c.Id));
            }
            if (goodsQuery.is_htl.HasValue) {
                if (goodsQuery.is_htl.Value == 0)
                    filter = filter.And(c => c.IsHtl == null || c.IsHtl == 0);
                else
                    filter = filter.And(c => c.IsHtl == goodsQuery.is_htl.Value);
            }

            if (goodsQuery.min_price != null && goodsQuery.min_price.Value > 0) {
                filter = filter.And(c => c.Price >= goodsQuery.min_price.Value);
            }
            if (goodsQuery.max_price != null && goodsQuery.max_price.Value > 0) {
                filter = filter.And(c => c.Price <= goodsQuery.max_price.Value);
            }

            //if (!string.IsNullOrEmpty(goodsQuery.Ids))
            //    filter.And(c => !goodsQuery.Ids.Contains(c.Id.ToString()));
            //filter =filter.And(!goodsQuery.Ids.Contains())
            if (!string.IsNullOrEmpty(goodsQuery.sku)) {
                filter = filter.And(c => c.Sku == goodsQuery.sku);
            }
            if (!string.IsNullOrEmpty(goodsQuery.keyword))
                filter = filter.And(c => c.Name.Contains(goodsQuery.keyword) || c.Code.Contains(goodsQuery.keyword));
            if (!string.IsNullOrEmpty(goodsQuery.tag))
                filter = filter.And(c => c.Tag == goodsQuery.tag);
            if (goodsQuery.audit_status == 0) {
                if (goodsQuery.sale_status == 1)
                    filter = filter.And(c => c.SaleStatus == SaleStatus.OutOfStock);
                else if (goodsQuery.sale_status == 2)
                    filter = filter.And(c => c.SaleStatus == SaleStatus.Sell || c.SaleStatus == SaleStatus.OutOfStock);
                else
                    filter = filter.And(c => c.SaleStatus == SaleStatus.Sell && c.AuditStatus != AuditStatus.Illegal);
            } else {
                if (goodsQuery.audit_status == 1)
                    filter = filter.And(c => c.AuditStatus == AuditStatus.Sell || c.AuditStatus == AuditStatus.PendingAudit);
                else if (goodsQuery.audit_status == 2)
                    filter = filter.And(c => c.AuditStatus == AuditStatus.PendingAudit && c.SaleStatus == SaleStatus.Sell);
                else if (goodsQuery.audit_status == 3)
                    filter = filter.And(c => c.AuditStatus == AuditStatus.Sell);
                else if (goodsQuery.audit_status == 4)
                    filter = filter.And(c => c.AuditStatus == AuditStatus.Illegal);
                else if (goodsQuery.audit_status == 5)
                    filter = filter.And(c => c.SaleStatus == SaleStatus.Delete);
            }
            if (goodsQuery.category_id > 0)
                filter = filter.And(c => c.CategoryId == goodsQuery.category_id || c.Category.ParentId == goodsQuery.category_id);
            if (goodsQuery.sell_id > 0)
                filter = filter.And(c => c.MerchantId == goodsQuery.sell_id);
            if (goodsQuery.merchant_id > 0)
                filter = filter.And(c => c.Merchant.OemId == goodsQuery.merchant_id || c.MerchantId == goodsQuery.merchant_id);
            if (goodsQuery.sell_out.HasValue) {
                if (goodsQuery.sell_out.Value)
                    filter = filter.And(c => c.Stock == 0);
                else
                    filter = filter.And(c => c.Stock > 0);
            }
            Func<IQueryable<Product>, IOrderedQueryable<Product>> orderBy = null;
            if (goodsQuery.sort == 1)
                orderBy = o => o.OrderByDescending(c => c.SaleCount);
            else if (goodsQuery.sort == 2)
                orderBy = o => o.OrderByDescending(c => c.Price);
            else if (goodsQuery.sort == 3)
                orderBy = o => o.OrderBy(c => c.Price);
            else if (goodsQuery.sort == 4)
                orderBy = o => o.OrderByDescending(c => c.CreateTime);
            else
                orderBy = o => o.OrderByDescending(c => c.Top);
            var result = context.Products.Where(filter).FromCachePaged(goodsQuery.page, goodsQuery.size, orderBy, (query, count_query) =>
            {
                var lists = query.ToList();
                var rows = lists.ToDtoList<product_dto>();
                return new PagedResult<product_dto>(rows, count_query.Count(), goodsQuery.page, goodsQuery.size);
            });

            return result;
        }
        /// <summary>
        /// 分销后台专用
        /// </summary>
        /// <param name="goodsQuery"></param>
        /// <returns></returns>
        public PagedResult<product_dto> GetForDistributionHt(GoodsQuery goodsQuery) {
            var filter = PredicateBuilder.True<Product>();
            if (goodsQuery.is_htl.HasValue) {
                if (goodsQuery.is_htl.Value == 0)
                    filter = filter.And(c => c.IsHtl == null || c.IsHtl == 0);
                else
                    filter = filter.And(c => c.IsHtl == goodsQuery.is_htl.Value);
            }
            if (goodsQuery.merchant_id > 0)
                filter = filter.And(c => c.Merchant.OemId == goodsQuery.merchant_id || c.MerchantId == goodsQuery.merchant_id);
            if (!string.IsNullOrEmpty(goodsQuery.sku)) {
                filter = filter.And(c => c.Sku == goodsQuery.sku);
            }
            if (!string.IsNullOrEmpty(goodsQuery.keyword))
                filter = filter.And(c => c.Name.Contains(goodsQuery.keyword) || c.Code.Contains(goodsQuery.keyword));
            if (goodsQuery.sale_status == 1)
                filter = filter.And(c => c.SaleStatus == SaleStatus.Sell);
            else if (goodsQuery.sale_status == 2)
                filter = filter.And(c => c.SaleStatus == SaleStatus.OutOfStock);
            else
                filter = filter.And(c => c.SaleStatus == SaleStatus.Delete);
            Func<IQueryable<Product>, IOrderedQueryable<Product>> orderBy = null;
            if (goodsQuery.sort == 1)
                orderBy = o => o.OrderByDescending(c => c.SaleCount);
            else if (goodsQuery.sort == 2)
                orderBy = o => o.OrderByDescending(c => c.Price);
            else if (goodsQuery.sort == 3)
                orderBy = o => o.OrderBy(c => c.Price);
            else if (goodsQuery.sort == 4)
                orderBy = o => o.OrderByDescending(c => c.CreateTime);
            else
                orderBy = o => o.OrderByDescending(c => c.Top);
            var result = context.Products.Where(filter).FromCachePaged(goodsQuery.page, goodsQuery.size, orderBy, (query, count_query) => {
                var lists = query.ToList();
                var rows = lists.ToDtoList<product_dto>();
                return new PagedResult<product_dto>(rows, count_query.Count(), goodsQuery.page, goodsQuery.size);
            });

            return result;
        }

        public async Task<int> GetProductSkus(GoodsQuery goodsQuery) {
            int count = 0;
            var filter = PredicateBuilder.True<Product>();
            filter = filter.And(c => c.IsHtl.HasValue && c.IsHtl.Value == 2);
            if (!string.IsNullOrEmpty(goodsQuery.sku))
                filter = filter.And(c => c.Sku == goodsQuery.sku);
            if (goodsQuery.sale_status == 0)
                filter = filter.And(c => c.SaleStatus == SaleStatus.Sell);
            else if (goodsQuery.sale_status == 1)
                filter = filter.And(c => c.SaleStatus == SaleStatus.OutOfStock);
            var products = context.Products.Where(filter).ToList();
            foreach (var product in products) {
                #region 商品详情
                //var req = new hn_goods_op_req {
                //    goodsSku = goodsQuery.sku
                //};
                //var api_result = await new HniaoMallSign().HniaoReq<hn_goods_op_res>(req);
                //if (api_result.data != null) {
                //    if (api_result.data.goodsDetail.spec != null) {
                //        var goods = context.Products.FirstOrDefault(c => c.Sku == goodsQuery.sku);
                //        var item = JObject.Parse(api_result.data.goodsDetail.spec.ToJson());
                //        var collection = item.ToObject<SortedDictionary<string, object>>();
                //        foreach (var kv in collection) {
                //            if (kv.Value is JArray) {
                //                int total = 0;
                //                var arrs = kv.Value as JArray;
                //                foreach (var spec in arrs) {
                //                    var goods_spec = spec.ToObject<hn_goods_spec>();
                //                    total += goods_spec.stock;
                //                    string skupath = string.Format("{0}-{1}", kv.Key, goods_spec.specNum);
                //                    var sku = goods.ProductSkus.FirstOrDefault(c => c.SkuPath == skupath);
                //                    if (sku != null) {
                //                        sku.StartExpDate = goods_spec.startExpDate;
                //                        sku.EndExpDate = goods_spec.endExpDate;
                //                        sku.CostPrice = goods_spec.specPrice;
                //                        sku.Stock = goods_spec.stock / goods_spec.specNum;
                //                    } else {
                //                        context.ProductSkus.Add(new ProductSku {
                //                            ProductId = goods.Id,
                //                            SkuName = goods_spec.specDesc,
                //                            SkuPath = skupath,
                //                            Price = goods_spec.specPrice,
                //                            CostPrice = goods_spec.specPrice,
                //                            Stock = goods_spec.stock / goods_spec.specNum,
                //                            Weight = 0,
                //                            StartExpDate = goods_spec.startExpDate,
                //                            EndExpDate = goods_spec.endExpDate
                //                        });
                //                    }
                //                    goods.Stock = total;
                //                }
                //            }
                //        }
                //        int result = _iUnitOfWork.Commit("Product" + goods.Id);
                //    }
                //} 
                #endregion

                #region 更新库存
                if (goodsQuery.tag == "goods.getStock") {
                    var req = new hn_goods_stock_req {
                        goodsSku = product.Sku
                    };
                    var api_result = await new HniaoMallSign().HniaoReq<hn_goods_stock_res>(req);
                    if (api_result.data != null) {
                        int total = 0;
                        foreach (var spec in api_result.data) {
                            total += spec.stockNum;
                            var skus = product.ProductSkus.Where(c => c.SkuPath.Contains(spec.specGroupName)).ToList();
                            foreach (var sku in skus) {
                                var arrs = sku.SkuPath.Split('-');
                                sku.StartExpDate = spec.startExpDate;
                                sku.EndExpDate = spec.endExpDate;
                                if (arrs.Length == 2) {
                                    sku.Stock = spec.stockNum / int.Parse(arrs[1]);
                                } else if (arrs.Length == 3) {
                                    sku.Stock = spec.stockNum / int.Parse(arrs[2]);
                                }
                            }
                        }
                        product.Stock = total;
                        int result = _iUnitOfWork.Commit("Product" + product.Id);
                    }
                }

                #endregion

                #region 更新价格
                if (goodsQuery.tag == "goods.getPrice") {
                    var goods_price_req = new hn_goods_price_req {
                        goodsSku = product.Sku
                    };
                    var api_result = await new HniaoMallSign().HniaoReq<hn_goods_price_res>(goods_price_req);
                    foreach (var spec in api_result.data) {
                        string sku_path = string.Empty;
                        foreach (var spec_detail in spec.specDetail) {
                            sku_path = string.Format("{0}-{1}", spec.specGroupName, spec_detail.specNum);
                            decimal cost_price = decimal.Parse(spec_detail.specPrice);
                            var sku = product.ProductSkus.FirstOrDefault(c => c.SkuPath == sku_path);
                            if (sku != null) {
                                if (cost_price > sku.CostPrice) {
                                    product.SaleStatus = SaleStatus.OutOfStock;
                                    product.ShortDescription = "候鸟价格变更成本价大于商城设置销售价，强制下架";
                                }
                                sku.CostPrice = cost_price;
                            } else {
                                context.ProductSkus.Add(new ProductSku {
                                    ProductId = product.Id,
                                    SkuName = spec_detail.specName,
                                    SkuPath = sku_path,
                                    Weight = 0,
                                    Price = cost_price * 1.2M,
                                    CostPrice = cost_price,
                                });
                            }
                        }
                    }
                    int result = _iUnitOfWork.Commit(string.Format("Product{0}", product.Id));
                }
                #endregion
                count++;
            }
            return await Task.FromResult(0);
        }

        /// <summary>
        /// 查询商品列表(含处理活动)
        /// </summary>
        /// <param name="goodsQuery"></param>
        /// <returns></returns>
        public PagedResult<product_dto> GetForActicity(GoodsQuery goodsQuery) {
            var result = Get(goodsQuery);
            if (result.rows != null && result.rows.Count() > 0) {
                foreach (var row in result.rows) {
                    _iProductActivityService.ProductActivityHandle(row, true);
                }
            }

            return result;
        }


        /// <summary>
        /// 是否已分销商品
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public bool IsShareProduct(distribution_goods_query query) {
            bool result = context.DistributionProducts.Any(c => c.ProductId == query.product_id &&
                                                           c.MerchantId == query.merchant_id && c.Status == EDistributionProductStatus.InSales);
            return result;
        }

        public PagedResult<product_shop_dto> GetShopGoods(GoodsQuery query) {
            /*
 select *,count(1) as total from ((select id,Name,Price,SaleCount,ImagePath,CreateTime,DistributionPrice 
 from mc_product where SaleStatus=0 and AuditStatus=1 and MerchantId=0)
union
(select b.id,b.Name,b.Price,b.SaleCount,b.ImagePath,b.CreateTime,b.DistributionPrice
from mc_DistributionProduct a left join mc_product b 
on a.ProductId = b.id where a.status=1 and a.MerchantId=0)) as w where w.Name like '%%' 
order by CreateTime,SaleCount OFFSET 1 ROW FETCH NEXT 20 ROW ONLY
 */
            StringBuilder sql = new StringBuilder();
            sql.Append("select * from ((");
            sql.Append("select Id as id,Name as name,Price as price,MarketPrice as market_price,SaleCount as sale_count,MainImageUrl as main_image_url,CreateTime as create_time,isnull(DistributionPrice,0) as distribution_price,0 as is_share, Stock as stock, isnull(CostPrice,0) as cost_price, Path as path ");
            sql.Append(string.Format("from mc_product where SaleStatus={0} and AuditStatus!={1} and MerchantId={2})", 1, 3, query.merchant_id));
            sql.Append(" union ");
            sql.Append("(select b.id,b.Name,b.Price,MarketPrice as market_price,b.SaleCount,b.MainImageUrl,b.CreateTime,isnull(b.DistributionPrice,0) as DistributionPrice,1 as is_share, b.Stock as stock, isnull(b.CostPrice,0) as cost_price, b.Path as path ");
            sql.Append("from mc_DistributionProduct a left join mc_product b on a.ProductId = b.id ");
            sql.Append(string.Format(" where a.status={0} and a.MerchantId={1})) as w ", 1, query.merchant_id));
            StringBuilder where = new StringBuilder();
            where.Append(" where 1=1 ");
            int page = (query.page - 1) * query.size;
            if (!string.IsNullOrEmpty(query.keyword)) {
                where.Append(string.Format("and name like '%{0}%'", query.keyword));
            }
            if (query.sell_out.HasValue) {
                if (query.sell_out.Value)
                    where.Append(" and stock = 0");
                else
                    where.Append(" and stock > 0");
            }
            sql.Append(where.ToString());
            var rows = context.Database.SqlQuery<int>(sql.Replace("*", "count(1)").ToString()).ToList();
            if (query.sort == 1) {
                //销量
                sql.Append(string.Format(" order by sale_count desc "));
            } else if (query.sort == 4) {
                //最新
                sql.Append(string.Format(" order by create_time desc "));
            }
            sql.Append(string.Format("OFFSET {0} ROW FETCH NEXT {1} ROW ONLY", page, query.size));
            var data = context.Database.SqlQuery<product_shop_dto>(sql.Replace("count(1)", "*").ToString()).ToList();
            var result = new PagedResult<product_shop_dto>(data, (rows.Count > 0 ? rows.First() : 0), query.page, query.size);
            //产品活动处理
            if (result.rows != null && result.rows.Count() > 0) {
                foreach (var row in result.rows) {
                    var product_dto = new product_dto() { id = row.id, price = row.price, path = row.path, distribution_price = row.distribution_price, cost_price = row.cost_price };
                    product_dto = _iProductActivityService.ProductActivityHandle(product_dto, true);
                    row.price = product_dto.price;
                    row.distribution_price = product_dto.distribution_price ?? 0;
                    row.activity_ex = product_dto.activity_ex;

                }
            }
            return result;
        }

        /// <summary>
        /// 购物车的商品集合请求返回最新价格、商品名称、图片、单价、市场价、卖家编号、是否可以购买
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public ApiResultMessage Cart(cart_req_model dto) {
            var log = new LogHelper("info");
            var errors = new List<string>();
            var pro_settles = new List<product_freight>();
            foreach (var cart in dto.items) {
                var product = Get(cart.product_id);
                var pro_settle = new product_freight {
                    product_id = cart.product_id,
                    type = 0,
                    sku_path = cart.sku_path,
                    is_buy = false,
                    fail = "商品不存在",
                    market_price = 0,
                    product_name = cart.product_name,
                    thumbnails_url = "",
                    unit_price = 0,
                    shop_name = "",
                    entrepot_name = ""
                };
                if (product != null) {
                    pro_settle = new product_freight {
                        product_id = product.id,
                        freight = product.freight ?? 0,
                        type = product.type,
                        sku_path = cart.sku_path,
                        is_buy = true,
                        fail = "",
                        merchant_no = product.bind_no,
                        market_price = product.market_price,
                        product_name = product.name,
                        thumbnails_url = product.first_image,
                        unit_price = product.price,
                        integral = product.integral,
                        tax = product.tax ?? 0,
                        weight = product.weight,
                        shop_name = product.merchant.name,
                        entrepot_name = ""
                        //entrepot_name = product.merchant.entrepot.entrepot_name
                    };
                    if (product.sale_status != SaleStatus.Sell || product.audit_status == AuditStatus.Illegal) {
                        pro_settle.fail = "已下架"; pro_settle.is_buy = false; pro_settles.Add(pro_settle);
                        continue;
                    }
                    if (product.product_skus.Count > 0) {
                        var product_sku = product.product_skus.FirstOrDefault(c => c.sku_path == cart.sku_path);
                        if (product_sku != null) {
                            pro_settle.sku_name = product_sku.sku_name;
                            if (product_sku.stock <= 0) {
                                pro_settle.fail = "库存不足"; pro_settle.is_buy = false; pro_settles.Add(pro_settle);
                                continue;
                            }
                            if (product_sku.price != cart.unit_price) {
                                pro_settle.fail = "已失效"; pro_settle.is_buy = false; pro_settles.Add(pro_settle);
                                continue;
                            }
                        } else {
                            pro_settle.fail = "商品不存在"; pro_settle.is_buy = false; pro_settles.Add(pro_settle);
                            continue;
                        }
                    } else {
                        if (product.stock <= 0) {
                            pro_settle.fail = "库存不足"; pro_settle.is_buy = false; pro_settles.Add(pro_settle);
                            continue;
                        }
                        if (product.price != cart.unit_price) {
                            pro_settle.fail = "已失效"; pro_settle.is_buy = false; pro_settles.Add(pro_settle);
                            continue;
                        }
                    }
                }
                pro_settles.Add(pro_settle);
            }
            log.Info(pro_settles.ToJson());
            var result = new ApiDataResultMessage<List<product_freight>>(pro_settles);
            return errors.Count > 0 ? new ApiResultMessage { result_code = 0, result_msg = errors.ToJson() } : result;
        }

        /// <summary>
        /// 用于校验确认订单数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public ApiResultMessage ValidProduct(cart_req_model dto) {
            var errors = new List<string>();
            var pro_settles = new List<product_freight>();
            bool is_mix = false, is_seas = false, first_time = true, last_status = false;
            decimal total_price = 0;
            foreach (var cart in dto.items) {
                var product = Get(cart.product_id);
                string sku_name = string.Empty;
                if (product != null) {
                    if (first_time) {
                        first_time = false;
                        last_status = product.is_seas;
                    }
                    if (product.is_seas != last_status) {
                        is_mix = true;
                        break;
                    }
                    if (product.is_seas) {
                        total_price += product.price * cart.quantity;
                        is_seas = product.is_seas;
                    }
                    if (product.sale_status != SaleStatus.Sell || product.audit_status == AuditStatus.Illegal) {
                        errors.Add(string.Format("该商品：【{0}】已下架或已删除", product.name));
                        continue;
                    }
                    if (product.stock <= 0) {
                        errors.Add(string.Format("该商品：【{0}】库存不足", product.name));
                        continue;
                    }
                    if (product.product_skus.Count > 0) {
                        var product_sku = product.product_skus.FirstOrDefault(c => c.sku_path == cart.sku_path);
                        if (product_sku != null) {
                            sku_name = product_sku.sku_name;
                            if (product_sku.stock <= 0) {
                                errors.Add(string.Format("该商品：【{0}】库存不足", product.name));
                                continue;
                            }
                            if (product_sku.price != cart.unit_price) {
                                errors.Add(string.Format("该商品：【{0}】销售价格错误", product.name));
                                continue;
                            }
                        } else {
                            errors.Add(string.Format("该商品：【{0}】不存在", cart.product_name));
                            continue;
                        }
                    } else {
                        if (product.price != cart.unit_price) {
                            errors.Add(string.Format("该商品：【{0}】销售价格错误", product.name));
                            continue;
                        }
                    }
                    pro_settles.Add(new product_freight {
                        product_id = product.id,
                        freight = product.freight ?? 0,
                        type = product.type,
                        is_seas = product.is_seas,
                        sku_path = cart.sku_path,
                        sku_name = sku_name,
                        is_buy = true,
                        fail = "",
                        merchant_no = product.bind_no,
                        market_price = product.market_price,
                        product_name = product.name,
                        thumbnails_url = product.first_image,
                        unit_price = product.price,
                        integral = product.integral,
                        points = product.points,
                        is_open = product.is_open,
                        tax = product.tax ?? 0,
                        weight = product.weight,
                        depth = product.depth ?? 0,
                        path = product.path,
                        distribution_price = product.distribution_price ?? 0,
                        is_tax = product.is_tax,
                        is_freight = product.is_freight,
                        cost_price = product.cost_price ?? 0
                    });
                } else {
                    //错误
                    errors.Add(string.Format("该商品：【{0}】不存在", cart.product_name));
                }
            }
            //如果境外商品则判断总价格不超过2k，单个商品不能超过2k。
            if (is_seas && total_price > 2000) {
                errors.Add("商品总价已超过2000元");
            }
            if (is_mix) {
                errors.Add("境外商品和大陆商品不能混合购买");
            }
            var result = new ApiDataResultMessage<List<product_freight>>(pro_settles);
            return errors.Count > 0 ? new ApiResultMessage { result_code = 0, result_msg = errors.ToJson() } : result;
        }

        /// <summary>
        /// 查询单个商品，包括促销活动，价格随活动价变化
        /// 优惠券集合、组合商品集合、（单品满包邮、全单促销集合）
        /// 判断是否秒杀、预售、拍卖
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public product_dto Get(long id) {
            var item = GetByBase(id);
            //var dt = DateTime.Now;
            //var sdt = dt.ToUnix();
            //var sale = context.Sales.FirstOrDefault(c => c.ProductId == item.id && c.Type == 2
            //		&& c.StartTime <= sdt && c.EndTime >= sdt && c.Status == 1);
            //if (sale != null)
            //	item.price = item.price * (1 - sale.SaleValue);
            if (item.audit_status == AuditStatus.Illegal)
                item.sale_status = SaleStatus.OutOfStock;

            return item;
        }
        /// <summary>
        /// 获取商品规格
        /// </summary>
        /// <param name="product_id"></param>
        /// <param name="sku_path"></param>
        /// <returns></returns>
        public product_sku_dto GetSku(long product_id, string sku_path) {
            var dto = context.ProductSkus.Where(s => s.ProductId == product_id && s.SkuPath == sku_path).FromCacheFirstOrDefault<ProductSku, product_sku_dto>();
            return dto;
        }
        /// <summary>
        /// 获得产品详情（含活动处理）
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isIncludePreHeat">是否包含预热</param> 
        /// <returns></returns>
        public product_dto GetForActicity(long id, bool isIncludePreHeat = false, bool isOnlyCashPay = false) {
            var result = Get(id);
            if (result != null)
                result = _iProductActivityService.ProductActivityHandle(result, isIncludePreHeat, isOnlyCashPay);
            return result;
        }
        /// <summary>
        /// 同类商品
        /// </summary>
        /// <param name="categroyId"></param>
        /// <param name="productId"></param>
        /// <returns></returns>
        public List<product_dto> GetLikeProducts(long categroyId, long productId) {
            var merchant = _iMerchantService.Get(t_RequestMethod.merchant_no);
            var list = context.Products.Where(s => s.Id != productId && (s.MerchantId == merchant.id || s.Merchant.OemId == merchant.id) && s.SaleStatus == SaleStatus.Sell && (s.AuditStatus == AuditStatus.Sell || s.AuditStatus == AuditStatus.PendingAudit)
                        && s.Stock > 0).FromCache(o =>
                        {
                            var temp = DateTime.Now.Millisecond;
                            if (temp == 0) temp = 1;
                            var result = o.OrderByDescending(s => s.CategoryId == categroyId).ThenByDescending(s => (s.CreateTime % temp)).Take(4).ToList().ToDtoList<product_dto>();
                            return result;
                        }, "LikeProduct_" + categroyId + "_" + productId);
            if (list != null) {
                for (int i = 0; i < list.Count(); i++) {
                    list[i] = _iProductActivityService.ProductActivityHandle(list[i], true);
                }
            }
            return list;
        }
        /// <summary>
        /// 获得产品规格详情（含活动处理）
        /// </summary>
        /// <param name="skuId"></param>
        /// <param name="isIncludePreHeat">是否包含预热</param>
        /// <returns></returns>
        public product_sku_dto GetSkuForActivity(long skuId, bool isIncludePreHeat = false, bool isOnlyCashPay = false) {
            var sku = context.ProductSkus.FindById(skuId).ToDtoObject<product_sku_dto>();
            if (sku != null)
                sku = _iProductActivityService.SkuActivityHandle(sku, isIncludePreHeat, isOnlyCashPay);
            return sku;
        }

        /// <summary>
        /// 获得产品扩展（用于分润计算）详情（含活动处理）
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="skuId"></param>
        /// <param name="isIncludePreHeat">是否包含预热</param>
        /// <param name="isOnlyCashPay">仅使用现金支付</param>
        /// <returns></returns>
        public product_calculate_ex GetCalculateExForActivity(long productId, long skuId = 0, bool isIncludePreHeat = false, bool isOnlyCashPay = false) {
            product_calculate_ex result = null;
            product_dto product = null;
            if (skuId > 0) {//有规格
                var sku = GetSkuForActivity(skuId, isIncludePreHeat, isOnlyCashPay);
                if (sku != null) {
                    product = GetForActicity(sku.product_id, isIncludePreHeat, isOnlyCashPay);
                    result = new product_calculate_ex() {
                        merchant_id = product.merchant_id,
                        price = sku.price,
                        activity_red_drill = sku.activity_ex != null ? sku.activity_ex.activity_red_drill : 0,
                        distribution_price = sku.distribution_price,
                        cost_price = sku.cost_price,
                        stock = sku.stock,
                        freight = product.freight ?? 0,
                        is_sale = true,
                        is_sold_out = (sku.activity_ex != null && sku.activity_ex.activity_type != EActivityType.ProductMaker) ? sku.activity_ex.is_sold_out : false,
                        product_source = product.is_htl,
                        activity_type = sku.activity_ex != null ?
                                        (sku.activity_ex.activity_type == EActivityType.ProductMaker ? 1 :
                                        sku.activity_ex.activity_type == EActivityType.ProductTimeBuy ? 2 :
                                        sku.activity_ex.activity_type == EActivityType.ProductCashRedDrill ? 3 :
                                        sku.activity_ex.activity_type == EActivityType.ProductOnlyRedDrill ? 4 : 0) : 0,
                        product_activity_id = sku.activity_ex == null ? null : sku.activity_ex.product_activity_id,
                        max_quantity = (sku.activity_ex != null && sku.activity_ex.activity_type != EActivityType.ProductMaker) ? sku.max_quantity : 0,
                        preheat_time = sku.activity_ex?.preheat_time,
                        begin_time = sku.activity_ex?.begin_time

                    };
                    if (result.is_sold_out || sku.stock <= 0 || !((product.audit_status == AuditStatus.Sell || product.audit_status == AuditStatus.PendingAudit) && product.sale_status == SaleStatus.Sell)) {
                        result.is_sale = false;
                    }

                    var skuPreHeat = GetSkuForActivity(skuId, true, isOnlyCashPay);
                    if (skuPreHeat.activity_ex != null && skuPreHeat.activity_ex.preheat_time != null && DateTime.Now < skuPreHeat.activity_ex.begin_time && DateTime.Now > skuPreHeat.activity_ex.preheat_time)
                        result.is_sale = false;//商品正在进行活动预热，不允许购买
                }

            } else {//无规格
                product = GetForActicity(productId, isIncludePreHeat, isOnlyCashPay);
                if (product != null) {
                    result = new product_calculate_ex() {
                        price = product.price,
                        activity_red_drill = product.activity_ex != null ? product.activity_ex.activity_red_drill : 0,
                        distribution_price = product.distribution_price ?? 0,
                        cost_price = product.cost_price ?? 0,
                        stock = product.stock,
                        merchant_id = product.merchant_id,
                        freight = product.freight ?? 0,
                        is_sale = true,
                        is_sold_out = (product.activity_ex != null && product.activity_ex.activity_type != EActivityType.ProductMaker) ? product.activity_ex.is_sold_out : false,
                        product_source = product.is_htl,
                        activity_type = product.activity_ex != null ?
                                        (product.activity_ex.activity_type == EActivityType.ProductMaker ? 1 :
                                        product.activity_ex.activity_type == EActivityType.ProductTimeBuy ? 2 :
                                        product.activity_ex.activity_type == EActivityType.ProductCashRedDrill ? 3 :
                                        product.activity_ex.activity_type == EActivityType.ProductOnlyRedDrill ? 4 : 0) : 0,
                        product_activity_id = product.activity_ex == null ? null : product.activity_ex.product_activity_id,
                        max_quantity = (product.activity_ex != null && product.activity_ex.activity_type != EActivityType.ProductMaker) ? product.max_quantity : 0,
                        preheat_time = product.activity_ex?.preheat_time,
                        begin_time = product.activity_ex?.begin_time
                    };
                    if (result.is_sold_out || product.stock <= 0 || !((product.audit_status == AuditStatus.Sell || product.audit_status == AuditStatus.PendingAudit) && product.sale_status == SaleStatus.Sell)) {
                        result.is_sale = false;
                    }
                    var productPreHeat = GetForActicity(productId, true, isOnlyCashPay);
                    if (productPreHeat.activity_ex != null && productPreHeat.activity_ex.preheat_time != null && DateTime.Now < productPreHeat.activity_ex.begin_time && DateTime.Now > productPreHeat.activity_ex.preheat_time)
                        result.is_sale = false;//商品正在进行活动预热，不允许购买

                }
            }
            return result;
        }

        /// <summary>
        /// 返回一条商品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private product_dto GetByBase(long id) {
            var result = context.Products.Where(c => c.Id == id).FromCacheFirstOrDefault<Product, product_dto>(query =>
            {
                var src = query.FirstOrDefault();
                if (src == null) return null;
                var dest = src.ToDtoObject<product_dto>();
                var merchant = _iMerchantService.Get(dest.merchant_id);
                dest.bind_no = merchant.merchant_no;
                if (dest.product_skus.Count > 0) {
                    if (dest.is_htl == 0) {
                        var first_sku_value = src.ProductSkus.First();
                        string[] sku_ids = first_sku_value.SkuPath.Split('-');
                        for (int i = 0; i < sku_ids.Length; i++) {
                            long sku_val_id = long.Parse(sku_ids[i]);
                            var sku_value = context.SkuValues.FindById(sku_val_id);
                            var sku_values = new List<sku_value_dto>();
                            foreach (var sku in src.ProductSkus) {
                                string[] path = sku.SkuPath.Split('-');
                                string[] arrs = sku.SkuName.Split(';');
                                var val_id = long.Parse(path[i]);
                                if (!sku_values.Any(c => c.id == val_id))
                                    sku_values.Add(new sku_value_dto { id = val_id, name = arrs[i].Split(':')[1] });
                            }
                            dest.sku_infos.Add(new sku_info_dto { id = sku_value.SkuId, name = sku_value.SkuInfo.Name, sku_values = sku_values });
                        }
                    } else if (dest.is_htl == 2) {
                        //var p_skus = dest.product_skus.Distinct(new ProductSkuComParer()).ToList();
                        //var sku_values = new List<sku_value_dto>();
                        //foreach (var item in p_skus) {
                        //    sku_value_dto dto = new sku_value_dto() { id = 0, name = item.sku_name, hn_id = item.sku_path };
                        //    sku_values.Add(dto);
                        //}
                        //dest.sku_infos.Add(new sku_info_dto { id = 0, name = "规格", sku_values = sku_values });
                        //dest.product_skus = p_skus;
                        List<product_sku_dto> list = new List<product_sku_dto>();
                        var p_sku = dest.product_skus.FirstOrDefault();
                        list.Add(p_sku);
                        var sku_values = new List<sku_value_dto>() { new sku_value_dto() { id = 0, name = p_sku.sku_name, hn_id = p_sku.sku_path } };
                        dest.sku_infos.Add(new sku_info_dto { id = 0, name = "规格", sku_values = sku_values });
                        dest.product_skus = list;
                    }
                }
                return dest;
            }, "Product" + id);
            return result;
        }
        public class ProductSkuComParer : IEqualityComparer<product_sku_dto> {
            public bool Equals(product_sku_dto x, product_sku_dto y) {
                return x.sku_path == y.sku_path;
            }
            public int GetHashCode(product_sku_dto obj) {
                return obj.ToString().GetHashCode();
            }
        }
        public int Add(product_dto dto, bool is_from_supplierpc = false) {
            if (dto.type == 5)
                throw new ServerErrorException("不允许直接添加创客类型商品，请先添加其他类型，再进入创客商品模块操作");
            if (dto.category_id == 0) dto.category_id = null;
            dto.audit_status = AuditStatus.PendingAudit;
            dto.create_time = DateTime.Now;
            var model = dto.ToDtoObject<Product>();
            model.CreateTime = dto.create_time.ToUnix();
            model.UpdateTime = model.CreateTime;
            if (is_from_supplierpc == true) {
                model.SaleStatus = dto.sale_status;
            } else {
                model.SaleStatus = SaleStatus.Sell;
            }
            model.Tax = dto.tax ?? 0;
            #region 规格
            if (dto.product_skus.Count > 0) {
                if (dto.product_skus.Any(c => string.IsNullOrEmpty(c.sku_path)))
                    dto.product_skus.ForEach((item, i) => { item.sku_path = "sku" + i; });
                model.ProductSkus = dto.product_skus.ToDtoList<ProductSku>().ToList();
                model.Price = dto.product_skus.Min(c => c.price);
                model.Stock = dto.product_skus.Sum(c => c.stock);
            }
            #endregion
            context.Products.Add(model);
            int result = _iUnitOfWork.Commit("Product" + dto.id);
            return result;
        }

        public int Update(product_dto dto, bool is_from_supplierpc = false) {
            if (dto.category_id == 0) dto.category_id = null;
            dto.audit_status = AuditStatus.PendingAudit;
            dto.update_time = DateTime.Now;
            if(is_from_supplierpc == false) {
                dto.sale_status = SaleStatus.Sell;
            }
            var model = context.Products.FindById(dto.id);
            if ((model.Type == 5 && dto.type != 5) || (model.Type != 5 && dto.type == 5))
                throw new ServerErrorException("不允许直接修改创客商品类型，或将其他类型商品设为创客类型商品，修改类型请到创客商品模块操作");
            dto.ToDtoObject(model);
            #region 规格
            if (dto.product_skus.Count > 0) {
                dto.product_skus.ForEach((item, i) =>
                {
                    if (string.IsNullOrEmpty(item.sku_path))
                        item.sku_path = "sku" + i;
                    item.product_id = dto.id;
                    //if (item.id == 0) item.id = DtoHelper.GuidToLongID();
                });
                model.Stock = dto.product_skus.Sum(c => c.stock);

                var req_ids = dto.product_skus.Select(c => c.sku_path);
                var data_ids = model.ProductSkus.Select(c => c.SkuPath).CopyToList();
                //新增
                req_ids.Except(data_ids).DataForEach(filter_id =>
                {
                    var item = dto.product_skus.First(c => c.sku_path == filter_id);
                    var model_item = item.ToDtoObject<ProductSku>();
                    model.ProductSkus.Add(model_item);
                });
                //删除
                data_ids.Except(req_ids).DataForEach(filter_id =>
                {
                    var model_item = model.ProductSkus.First(c => c.SkuPath == filter_id);
                    context.Entry(model_item).State = EntityState.Deleted;
                });
                //更新
                req_ids.Intersect(data_ids).DataForEach(filter_id =>
                {
                    var item = dto.product_skus.First(c => c.sku_path == filter_id);
                    var model_item = model.ProductSkus.First(c => c.SkuPath == filter_id);
                    var skuid = model_item.Id;
                    item.ToDtoObject(model_item);
                    model_item.Id = skuid;
                    context.Entry(model_item).State = EntityState.Modified;
                });
            } else {
                model.ProductSkus.DataForEach((model_item, i) =>
                {
                    context.Entry(model_item).State = EntityState.Deleted;
                });
            }
            #endregion

            int result = _iUnitOfWork.Commit("Product" + dto.id);
            return result;
        }

        public ApiResultMessage Save(product_model dto) {
            int result = 0;
            var model = dto.ToDtoObject<product_dto>();
            var user = _iMerchantService.Get(dto.bind_no);
            if (dto.price <= 0 || dto.cost_price <= 0) {
                throw new ServerErrorException("销售价或者成本价不能为0");
            } else {
                if (dto.price < dto.cost_price)
                    throw new ServerErrorException("销售价不能低于成本价");
            }

            foreach (var sku in dto.product_skus) {
                if (sku.price <= 0 || sku.cost_price <= 0) {
                    throw new ServerErrorException("销售价或者成本价不能为0");
                } else {
                    if (sku.price < sku.cost_price)
                        throw new ServerErrorException("销售价不能低于成本价");
                }
            }
            model.merchant_id = user.id;
            if (dto.id > 0)
                result = Update(model);
            else
                result = Add(model);
            return ApiResultToJson.Success("保存成功");
        }

        public ApiResultMessage SaveHniaoProduct(product_model dto) {
            int result = 0;
            var model = dto.ToDtoObject<product_dto>();
            if (model.category_id == 0) dto.category_id = null;
            model.audit_status = AuditStatus.PendingAudit;
            model.update_time = DateTime.Now;
            var user = _iMerchantService.Get(dto.bind_no);
            model.merchant_id = user.id;
            decimal percent = 0;
            if (string.IsNullOrEmpty(dto.path) || !decimal.TryParse(dto.path, out percent))
                percent = 1;
            else
                percent = decimal.Parse(dto.path);
            if (percent > 1) percent = 1;
            var product = context.Products.FindById(dto.id);
            model.ToDtoObject(product);
            if (dto.product_skus.Count > 0) {
                var product_sku = dto.product_skus.FirstOrDefault(c => c.cost_price == dto.product_skus.Max(d => d.cost_price));
                product.CostPrice = product_sku.cost_price;
                product.Stock = product_sku.stock;
            } else {
                product.Stock = 0;
            }

            //foreach (var sku in model.product_skus) {
            //    if (sku.price <= sku.cost_price)
            //        return ApiResultToJson.Fail("销售价不能小于等于成本价");
            //    var psku = product.ProductSkus.FirstOrDefault(c => c.SkuPath == sku.sku_path);
            //    if (psku != null) {
            //        psku.Price = sku.price;
            //        psku.DistributionPrice = (sku.price - sku.cost_price) * percent;
            //        psku.Stock = sku.stock;
            //        psku.StartExpDate = sku.start_Exp_Date;
            //        psku.EndExpDate = sku.end_Exp_Date;
            //    }
            //}
            result = _iUnitOfWork.Commit("Product" + dto.id);
            return result >= 0 ? ApiResultToJson.Success("保存成功") : ApiResultToJson.Fail("保存失败");
        }
        public int Audit(long id, AuditStatus audit_status, string audit_reason) {
            var model = context.Products.FindById(id);
            model.AuditReason = audit_reason;
            model.AuditStatus = audit_status;

            if (audit_status == AuditStatus.Illegal && !string.IsNullOrEmpty(audit_reason)) {
                //保存消息
                var replyMessage = new MessagePush();
                replyMessage.MerchantId = model.MerchantId;
                replyMessage.Type = MsgType.ProductPass;
                replyMessage.Title = model.Name + " 审核通知";
                replyMessage.ShortContent = audit_reason;
                replyMessage.Content = audit_reason;
                replyMessage.Ext = "{}";
                replyMessage.CreateTime = DateTime.Now.ToUnix();
                replyMessage.ObjectId = model.Id;
                replyMessage.Url = t_RequestMethod.token_url + "productmanage/productlist";
                context.MessagePushs.Add(replyMessage);

                //发送消息
                try {
                    JPushHelp jPushHelp = new JPushHelp(t_RequestMethod.push_app_key, t_RequestMethod.push_app_secret);
                    jPushHelp.Push(replyMessage.Title, replyMessage.Content, (int)replyMessage.Type, replyMessage.ObjectId.Value, new List<string> { model.Merchant.Mobile }, replyMessage.Url);
                }
                catch { }
            }
            int result = _iUnitOfWork.Commit("Product" + id);
            return result;
        }

        /// <summary>
        /// 上下架：返回1下架，2上架,0失败
        /// </summary>
        /// <returns>The down.</returns>
        /// <param name="id">Identifier.</param>
        public int UpDown(long id) {
            var tags = new List<string> { "Product" + id };
            var model = context.Products.FindById(id);
            var distributions = context.DistributionProducts.Where(c => c.ProductId == id).ToList();
            if (model.SaleStatus == SaleStatus.OutOfStock) {
                model.SaleStatus = SaleStatus.Sell;
                distributions.DataForEach(distribution =>
                {
                    distribution.Status = EDistributionProductStatus.InSales;
                    tags.Add("DistributionProduct" + distribution.MerchantId);
                });
            } else {
                model.SaleStatus = SaleStatus.OutOfStock;
                model.AuditStatus = AuditStatus.PendingAudit;
                distributions.DataForEach(distribution =>
                {
                    distribution.Status = EDistributionProductStatus.Failure;
                    tags.Add("DistributionProduct" + distribution.MerchantId);
                });
            }
            int result = _iUnitOfWork.Commit(tags.ToArray());
            if (result > 0) {
                if (model.SaleStatus == SaleStatus.OutOfStock)
                    return 1;
                return 2;
            }
            return result;
        }
        /// <summary>
        /// 编辑产品分类
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="categoryId"></param>
        /// <returns></returns>
        public int EditProductCategory(long productId, long categoryId) {
            var model = context.Products.FindById(productId);
            model.CategoryId = categoryId;
            int result = _iUnitOfWork.Commit("Product" + productId);
            return result;
        }
        public int Delete(long id) {
            var model = context.Products.FindById(id);
            model.SaleStatus = SaleStatus.Delete;
            model.AuditStatus = AuditStatus.Delete;
            int result = _iUnitOfWork.Commit("Product" + id);
            return result;
        }
        public ApiResultMessage DeleteProduct(long id) {
            var model = context.Products.FindById(id);
            model.SaleStatus = SaleStatus.Delete;
            model.AuditStatus = AuditStatus.Delete;
            int result = _iUnitOfWork.Commit("Product" + id);
            if (result > 0)
                return ApiResultToJson.Success("删除成功");
            else
                return ApiResultToJson.Fail("删除失败");
        }

        public void MinusStock(Data.Order order, List<string> cacheList = null) {
            if (cacheList == null)
                cacheList = new List<string>();
            order.OrderItems.ForEach(c =>
            {
                var product = context.Products.FirstOrDefault(s => s.Id == c.ProductId);
                if (product != null) {
                    product.SaleCount += c.Quantity;
                    product.Stock -= c.Quantity;
                    cacheList.Add("Product" + product.Id);
                }
                if (c.SkuId.HasValue && c.SkuId.Value > 0) {
                    var item = context.ProductSkus.FirstOrDefault(s => s.Id == c.SkuId.Value);
                    if (item != null)
                        item.Stock -= c.Quantity;
                }

                if (c.ProductActivityId != null && c.ProductActivityId > 0) {//活动商品

                    var productActivity = context.ProductActivity.FindById(c.ProductActivityId);
                    if (productActivity != null) {
                        //纯红钻兑换，判断库存，防止并发
                        if(productActivity.Activity != null && productActivity.Activity.Type == EActivityType.ProductOnlyRedDrill &&
                            (product.Stock <= 0 || productActivity.ActivityStock <= 0)) {
                            throw new ServerErrorException("商品已售罄");
                        }

                        //1.增加销售量
                        productActivity.SaleCount += c.Quantity;
                        //2.增加参与数
                        if (productActivity.Activity != null)
                            productActivity.Activity.ParticipationNum += 1;
                        //3.扣减活动库存
                        productActivity.ActivityStock -= c.Quantity;
                        //4.判断限时购是否售罄
                        if (product != null && (product.Stock <= 0 || productActivity.ActivityStock <= 0) && productActivity.ProductActivityTimeBuy != null) {
                            productActivity.IsSoldOut = true;
                        }
                    }

                    cacheList.Add("ProductActivity" + c.ProductId);
                    cacheList.Add("Activity");
                }
            });
        }
        /// <summary>
        /// 保存token商品
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool SaveTokenProduct(token_product_dto model) {
            var merchant = _iMerchantService.Get(model.merchant_id);
            if (!merchant.is_supplier) { throw new ServerErrorException("您无权限发布商品"); }
            if (model.cost_price > model.price) model.cost_price = model.price;
            //if (model.status == 1 && model.stock <= 0) model.stock = 1;
            if (model.cost_price > model.price)
                throw new ServerErrorException("结算价不能大于销售价");
            if (model.status == 1 && model.stock <= 0)
                throw new ServerErrorException("库存不足无法上架");
            var shopInfo = _iShopInfoService.GetShopById(merchant.id);
            if (shopInfo == null && merchant.is_supplier == true)
                throw new ServerErrorException("请在个人中心 -> 我的商城 -> 商城管理，维护商城信息");
            if (shopInfo == null || shopInfo.is_disabled == true)
                throw new ServerErrorException("店铺已经被冻结，无法发布商品");
            if (model.id == 0) {
                var product = model.ToDtoObject<Product>();
                product.CreateTime = product.UpdateTime = DateTime.Now.ToUnix();
                product.AuditStatus = AuditStatus.PendingAudit;
                product.SaleStatus = SaleStatus.Sell;
                product.Path = "1";
                product.DistributionPrice = (product.Price - product.CostPrice);
                product.IsApp = true;
                product.Type = 1;
                //product.DistributionPrice = (product.Price - product.CostPrice) * 0.8M;
                //if (product.Price == product.CostPrice.Value) {
                //    product.CostPrice = product.CostPrice - product.CostPrice * 0.02M;
                //}
                context.Products.Add(product);

                int r = _iUnitOfWork.Commit();
                return r > 0;
            } else {
                var product = context.Products.FindById(model.id);
                var oldimgs = product.ImagePath.ToObject<List<string>>();
                var old_procuct_desc_imgs = !string.IsNullOrEmpty(product.Description) ? HtmlContentHelper.GetHtmlImageUrlList(product.Description).ToList() : new List<string>();
                model.ToDtoObject(product);
                product.AuditStatus = AuditStatus.PendingAudit;
                product.DistributionPrice = (product.Price - product.CostPrice);
                product.UpdateTime = DateTime.Now.ToUnix();
                product.IsApp = true;
                product.Type = 1;
                //product.DistributionPrice = (product.Price - product.CostPrice) * 0.8M;
                //if (product.Price == product.CostPrice.Value) {
                //    product.CostPrice = product.CostPrice - product.CostPrice * 0.02M;
                //}

                int r = _iUnitOfWork.Commit("Product" + model.id);
                if (r > 0) {
                    if (model.product_imgs.Count > 0 && oldimgs.Count > 0) {
                        var oss = new AliyunOSS(DtoHelper._accessKeyId, DtoHelper._accessKeySecret, "");
                        //删除
                        oldimgs.Except(model.product_imgs).DataForEach(filter_id =>
                        {
                            oss.DeleteObject(DtoHelper.oss_bucketName, filter_id.Replace(RequestMethod.token_imgurl, "").Replace("http://img.timebiz.cn/", "").Trim('/'));
                        });
                    }
                    if (model.procuct_desc_imgs.Count > 0 && old_procuct_desc_imgs.Count > 0) {
                        var oss = new AliyunOSS(DtoHelper._accessKeyId, DtoHelper._accessKeySecret, "");
                        //删除
                        old_procuct_desc_imgs.Except(model.procuct_desc_imgs).DataForEach(filter_id =>
                        {
                            oss.DeleteObject(DtoHelper.oss_bucketName, filter_id.Replace(RequestMethod.token_imgurl, "").Replace("http://img.timebiz.cn/", "").Trim('/'));
                        });
                    }
                }
                return r > 0;
            }
        }
        public token_product_dto GetTokenProduct(long id) {
            var model = context.Products.FindById(id).ToDtoObject<token_product_dto>();
            return model;
        }

        #region 拓垦商城-商品管理
        /// <summary>
        /// 拓垦节点商城-商品管理列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public PagedResult<token_product_manage_dto> GetTokenProductManageList(TokenProductQuery query, bool isFromSupplierPC = false) {
            //自营商品
            var q1 = context.Products.Where(o => o.MerchantId == query.merchant_id && o.SaleStatus != SaleStatus.Delete).Select(o => new token_product_manage_dto {
                product_id = o.Id,
                distribution_product_id = 0,
                is_proprietary = true,
                main_img_url = o.MainImageUrl,
                name = o.Name,
                price = o.Price,
                stock = o.Stock,
                sale_count = o.SaleCount,
                freight = o.Freight,
                distribution_price = o.DistributionPrice ?? 0,
                status = (o.SaleStatus == SaleStatus.Sell && (o.AuditStatus == AuditStatus.PendingAudit || o.AuditStatus == AuditStatus.Sell) && o.Stock > 0) ? EDistributionProductStatus.InSales :
                         (o.Stock == 0) ? EDistributionProductStatus.SoldOut : EDistributionProductStatus.InStock,
                audit_status = o.AuditStatus,
                is_app = o.IsApp,
                audit_reason = o.AuditReason,
                create_time_value = o.CreateTime,
            });
            //分销商品
            var q2 = context.DistributionProducts.Where(o => o.MerchantId == query.merchant_id && o.Status != EDistributionProductStatus.Deleted).Select(o => new token_product_manage_dto {
                product_id = o.Product.Id,
                distribution_product_id = o.Id,
                is_proprietary = false,
                main_img_url = o.Product.MainImageUrl,
                name = o.Product.Name,
                price = o.Product.Price,
                stock = o.Product.Stock,
                sale_count = o.Product.SaleCount,
                freight = o.Product.Freight,
                distribution_price = o.Product.DistributionPrice ?? 0,
                status = o.Status,
                audit_status = o.Product.AuditStatus,
                is_app = o.Product.IsApp,
                audit_reason = o.Product.AuditReason,
                create_time_value = o.Product.CreateTime,
            });
            var q = q1.Union(q2);
            if (query.status > 0) {
                if (isFromSupplierPC) {//来自供应商PC 违规下架与仓库中区分
                    if (query.status == 6)
                        q = q.Where(o => o.audit_status == AuditStatus.Illegal && o.status == EDistributionProductStatus.InStock);
                    else
                        q = q.Where(o => o.status == (EDistributionProductStatus)query.status && o.audit_status != AuditStatus.Illegal);

                } else {
                    q = q.Where(o => o.status == (EDistributionProductStatus)query.status);
                }
            }
            if (!string.IsNullOrEmpty(query.product_name))
                q = q.Where(o => o.name.Contains(query.product_name));

            if (isFromSupplierPC) {//来自供应商PC 其他查询条件
                if (query.begin_time != null) {
                    long value = ((DateTime)query.begin_time).ToUnix();
                    q = q.Where(o => o.create_time_value >= value);
                }
                if (query.end_time != null) {
                    long value = ((DateTime)query.end_time).ToUnix();
                    q = q.Where(o => o.create_time_value <= value);
                }
                if (query.min_price > 0)
                    q = q.Where(o => o.price >= query.min_price);
                if (query.max_price > 0)
                    q = q.Where(o => o.price <= query.max_price);
            }

            var rows = q.OrderByDescending(o => o.product_id).Skip((query.page - 1) * query.size).Take(query.size).ToList();
            foreach(var row in rows) {
                row.create_time = row.create_time_value.ToDateTime();
                if (isFromSupplierPC) {
                    var product = GetByBase(row.product_id);
                    row.sku_name_list = (product != null && product.product_skus != null) ? product.product_skus.Select(s => s.sku_name).ToList() : new List<string>();
                }
            }
            var result = new PagedResult<token_product_manage_dto>(rows, q.Count(), query.page, query.size);
            return result;
        }

        /// <summary>
        /// 变更拓垦商城-商品管理状态
        /// </summary>
        /// <param name="product_id"></param>
        /// <param name="distribution_product_id"></param>
        /// <param name="is_proprietary"></param>
        /// <param name="status">状态（1：上架，2：下架，3：删除）</param>
        /// <returns></returns>
        public bool UpdateTokenProductStatus(long product_id, long distribution_product_id, bool is_proprietary, int status, long merchant_id) {
            var result = false;
            var shopInfo = _iShopInfoService.GetShopById(merchant_id);
            if (shopInfo == null || shopInfo.is_disabled == true)
                throw new ServerErrorException("店铺已经被冻结");
            if (is_proprietary) {//自营商品
                var cacheTags = new List<string>();
                var product = context.Products.Where(o => o.Id == product_id && o.MerchantId == merchant_id).FirstOrDefault();
                if (status == 1) {//上架
                    if (product.AuditStatus == AuditStatus.Illegal)
                        throw new ServerErrorException("该商品由违规下架请修改后上架");
                    else if (product.Stock <= 0)
                        throw new ServerErrorException("商品库存不足，无法上架");

                    product.SaleStatus = SaleStatus.Sell;
                } else if (status == 2) {//下架
                    product.SaleStatus = SaleStatus.OutOfStock;
                } else if (status == 3) {//删除
                    product.SaleStatus = SaleStatus.Delete;
                }
                var distributionProductList = context.DistributionProducts.Where(o => o.ProductId == product_id && o.Status != EDistributionProductStatus.Deleted).ToList();
                if (status == 2 || status == 3) {//下架、删除
                    //将对应的分销表数据状态改为已失效
                    distributionProductList.DataForEach(dp =>
                    {
                        dp.Status = EDistributionProductStatus.Failure;
                        cacheTags.Add("DistributionProduct" + dp.MerchantId);
                    });
                } else {
                    distributionProductList.Where(c => c.Status == EDistributionProductStatus.Failure).DataForEach(dp =>
                    {
                        dp.Status = EDistributionProductStatus.InSales;
                        cacheTags.Add("DistributionProduct" + dp.MerchantId);
                    });
                }

                cacheTags.Add("Product" + product_id);
                result = _iUnitOfWork.Commit(cacheTags.ToArray()) > 0;
            } else {//分销商品
                var distribution_product = context.DistributionProducts.Where(o => o.Id == distribution_product_id && o.MerchantId == merchant_id).FirstOrDefault();
                if (status == 1) {//上架
                    if (distribution_product.Product.Stock <= 0)
                        throw new ServerErrorException("商品库存不足，无法上架");
                    if (distribution_product.Product.AuditStatus != AuditStatus.Sell && distribution_product.Product.SaleStatus != SaleStatus.Sell)
                        throw new ServerErrorException("该商品未加入云商品库，无法上架");
                    distribution_product.Status = EDistributionProductStatus.InSales;
                } else if (status == 2)//下架（分销商品下架变为已失效，自营商品下架变为库存中）
                    distribution_product.Status = EDistributionProductStatus.Failure;
                else if (status == 3)//删除
                    distribution_product.Status = EDistributionProductStatus.Deleted;

                result = _iUnitOfWork.Commit("DistributionProduct" + merchant_id) > 0;
            }

            return result;
        }
        #endregion

        public async Task<product_sku_info> SearchSkuInfo(string sku) {
            var skus = new List<product_sku_dto>();
            var req = new hn_goods_op_req {
                goodsSku = sku
            };
            var result = await new HniaoMallSign().HniaoReq<hn_goods_op_res>(req);
            if (result.data != null) {
                if (result.data.goodsDetail.spec != null) {
                    var item = JObject.Parse(result.data.goodsDetail.spec.ToJson());
                    var collection = item.ToObject<SortedDictionary<string, object>>();
                    foreach (var kv in collection) {
                        if (kv.Value is JArray) {
                            var arrs = kv.Value as JArray;
                            foreach (var spec in arrs) {
                                var hn_spec = spec.ToObject<hn_goods_spec>();
                                var goods_spec = hn_spec.ToDtoObject<product_sku_dto>();
                                if (hn_spec.specNum == 1) {
                                    goods_spec.sku_path = string.Format("{0}-{1}", kv.Key, hn_spec.specNum);
                                    goods_spec.cost_price = goods_spec.price;
                                    goods_spec.start_Exp_Date = goods_spec.start_Exp_Date ?? "";
                                    goods_spec.end_Exp_Date = goods_spec.end_Exp_Date ?? "";
                                    skus.Add(goods_spec);
                                }
                            }
                        }
                    }
                }
            }
            return new product_sku_info { sku = sku, skus = skus };
        }
        /// <summary>
        /// 修改商品sku保质期
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public int SaveProductSku(product_sku_info dto) {
            string sku_path = string.Format("{0}-1", dto.sku);
            var product = context.Products.FirstOrDefault(c => c.Sku == dto.sku);
            var sku = product.ProductSkus.FirstOrDefault(c => c.SkuPath == sku_path);
            if (sku != null) {
                sku.StartExpDate = dto.start_time;
                sku.EndExpDate = dto.end_time;
            } else {
                var sku_dto = dto.skus.FirstOrDefault(c => c.price == product.CostPrice);
                if (sku_dto == null) {
                    sku_dto = new product_sku_dto {
                        product_id = product.Id,
                        sku_name = "1支装",
                        sku_path = sku_path,
                        price = product.CostPrice ?? 0,
                        stock = product.Stock,
                        start_Exp_Date = "",
                        end_Exp_Date = ""
                    };
                }
                context.ProductSkus.Add(new ProductSku {
                    ProductId = product.Id,
                    SkuName = sku_dto.sku_name,
                    Price = sku_dto.price,
                    SkuPath = sku_path,
                    Stock = sku_dto.stock,
                    StartExpDate = sku_dto.start_Exp_Date,
                    EndExpDate = sku_dto.end_Exp_Date,
                    Weight = 0
                });
            }
            int result = _iUnitOfWork.Commit("Products" + product.Id);
            return result;
        }
    }
}